package cn.blnp.net.flowable.boot.localize.task.recall;

import cn.blnp.net.flowable.boot.service.TaskRecallService;
import cn.blnp.net.flowable.boot.utils.ListUtils;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricActivityInstanceQuery;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ExecutionQuery;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <h3>任务撤回案例演示</h3>
 *
 * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
 * @version 1.0
 * @since 2025/6/19 9:32
 */
@Slf4j
@SpringBootTest
public class TaskRecallTest {

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private IdentityService identityService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;
    @Resource
    private TaskRecallService taskRecallService;

    SimplePropertyPreFilter taskFilter = new SimplePropertyPreFilter(Task.class,
            "id", "name", "executionId", "taskDefinitionKey");
    SimplePropertyPreFilter executionFilter = new SimplePropertyPreFilter(Execution.class,
            "id", "parentId", "processInstanceId", "activityId", "isScope");
    SimplePropertyPreFilter historicActivityFilter =
            new SimplePropertyPreFilter(HistoricActivityInstance.class,
                    "id", "activityId", "activityName", "taskId");

    /**
     *  <h1>任务撤回流程演示用例</h1>
     *  <ul>
     *      <li><b>流程定义文件：</b>{@link flow/taskRecallProcess.bpmn20.xml}</li>
     *      <li>
     *          <b>流程预览图：</b></br>
     *          <img src="https://cdn4.winhlb.com/2025/06/19/685369e3e128e.png" >
     *      </li>
     *  </ul>
     **/
    @Test
    public void test() throws InterruptedException {
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("flow/taskRecallProcess.bpmn20.xml")
                .name("流程任务撤回案例演示")
                .deploy();
        log.info("部署ID：{}", deploy.getId());
        //流程定义信息
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploy.getId())
                .singleResult();
        log.info("流程定义ID：{}", processDefinition.getId());
        //启动流程实例
        ProcessInstance procInst = runtimeService.startProcessInstanceById(processDefinition.getId());
        log.info("流程实例ID：{}", procInst.getId());
        TaskQuery taskQuery = taskService.createTaskQuery()
                .processInstanceId(procInst.getId());
        ExecutionQuery executionQuery = runtimeService.createExecutionQuery()
                .processInstanceId(procInst.getId());
        HistoricActivityInstanceQuery hisActivityQuery = historyService
                .createHistoricActivityInstanceQuery()
                .processInstanceId(procInst.getId());

        //查询借款申请用户任务的task
        Task firstTask = taskQuery.singleResult();
        //完成借款申请用户任务的task
        taskService.complete(firstTask.getId());
        //进行休眠等待
        Thread.sleep(50*1000);
        log.info("撤回前，当前任务为：{}", JSON.toJSONString(taskQuery.list(), taskFilter));
        log.info("当前执行实例有：{}", JSON.toJSONString(executionQuery.list(), executionFilter));
        log.info("历史节点实例有：{}", JSON.toJSONString(hisActivityQuery.list(), historicActivityFilter));

        //执行撤回操作
        taskRecallService.executeRecall(firstTask.getId());

        log.info("撤回后，当前任务为：{}", JSON.toJSONString(taskQuery.list(), taskFilter));
        log.info("当前执行实例有：{}", JSON.toJSONString(executionQuery.list(), executionFilter));
        log.info("历史节点实例有：{}", JSON.toJSONString(hisActivityQuery.list(), historicActivityFilter));

        /**
         *  演示结果：
         *  2025-06-19 09:43:56.846  INFO 50560 --- [           main] c.b.n.f.b.l.task.recall.TaskRecallTest   : 部署ID：240001
         * 2025-06-19 09:43:56.852  INFO 50560 --- [           main] c.b.n.f.b.l.task.recall.TaskRecallTest   : 流程定义ID：taskRecallProcess:1:240004
         * 2025-06-19 09:43:56.922  INFO 50560 --- [           main] c.b.n.f.b.l.task.recall.TaskRecallTest   : 流程实例ID：240005
         * 2025-06-19 09:43:57.260  INFO 50560 --- [           main] c.b.n.f.b.l.task.recall.TaskRecallTest   : 撤回前，当前任务为：[{"executionId":"240006","id":"240018","name":"直属上级审批","taskDefinitionKey":"userTask2"},{"executionId":"240014","id":"240021","name":"财务经理审批","taskDefinitionKey":"userTask3"}]
         * 2025-06-19 09:43:57.286  INFO 50560 --- [           main] c.b.n.f.b.l.task.recall.TaskRecallTest   : 当前执行实例有：[{"id":"240005","isScope":true,"processInstanceId":"240005"},{"activityId":"userTask2","id":"240006","isScope":false,"parentId":"240005","processInstanceId":"240005"},{"activityId":"userTask3","id":"240014","isScope":false,"parentId":"240005","processInstanceId":"240005"}]
         * 2025-06-19 09:43:57.299  INFO 50560 --- [           main] c.b.n.f.b.l.task.recall.TaskRecallTest   : 历史节点实例有：[{"activityId":"startEvent1","id":"240007"},{"activityId":"seqFlow1","id":"240008"},{"activityId":"userTask1","activityName":"借款申请","id":"240009","taskId":"240010"},{"activityId":"seqFlow2","id":"240012"},{"activityId":"parallelGateway1","id":"240013"},{"activityId":"seqFlow3","id":"240015"},{"activityId":"seqFlow4","id":"240016"},{"activityId":"userTask2","activityName":"直属上级审批","id":"240017","taskId":"240018"},{"activityId":"userTask3","activityName":"财务经理审批","id":"240020","taskId":"240021"}]
         * 2025-06-19 09:43:57.387  INFO 50560 --- [           main] c.b.n.f.b.l.task.recall.TaskRecallTest   : 撤回后，当前任务为：[{"executionId":"240023","id":"240025","name":"借款申请","taskDefinitionKey":"userTask1"}]
         * 2025-06-19 09:43:57.392  INFO 50560 --- [           main] c.b.n.f.b.l.task.recall.TaskRecallTest   : 当前执行实例有：[{"id":"240005","isScope":true,"processInstanceId":"240005"},{"activityId":"userTask1","id":"240023","isScope":false,"parentId":"240005","processInstanceId":"240005"}]
         * 2025-06-19 09:43:57.397  INFO 50560 --- [           main] c.b.n.f.b.l.task.recall.TaskRecallTest   : 历史节点实例有：[{"activityId":"startEvent1","id":"240007"},{"activityId":"seqFlow1","id":"240008"},{"activityId":"userTask1","activityName":"借款申请","id":"240024","taskId":"240025"}]
         **/
    }
}
